#include <QApplication>
#include <QIcon>
#include <QSlider>
#include <QAction>
#include <QToolBar>
#include <QLCDNumber>
#include <QToolButton>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QGraphicsView>
#include <QBrush>
#include <QFileDialog>
#include <QTimer>
#include <QString>
#include <QDial>

#include "iceplayerwindow.h"
#include "mplayercontroller.h"
#include "settingdialog.h"

IcePlayerWindow::IcePlayerWindow(QWidget *parent)
    : QMainWindow(parent),mplayerController(NULL),currentMediaFile("")
{
    createActions();
    createToolBar();
    createWidgets();
    createLayout();
    createTimer();
    createConnections();

    setWindowTitle(QApplication::applicationName());
}

void IcePlayerWindow::createActions()
{
    chooseVideoAction = new QAction(QIcon(":/images/video_folder.png"),
        tr("Open Videos"), this);
    playOrPauseAction = new QAction(QIcon(":/images/play.png"),
        tr("Play/Pause"), this);
    stopAction = new QAction(QIcon(":/images/stop.png"),
            tr("Stop."), this);
    fullScreenAction = new QAction(QIcon(":/images/fullscreen.png"),
            tr("Show Full-screen."), this);
    settingAction = new QAction(QIcon(":/images/setting.png"),
            tr("settings."), this);
}
void IcePlayerWindow::createTimer()
{
    stopwatchTimer = new QTimer(this);
    stopwatchTimer->start(1000);
}

void IcePlayerWindow::createToolBar()
{
    toolbar = new QToolBar(this);
    toolbar->addAction(chooseVideoAction);
    toolbar->addAction(playOrPauseAction);
    toolbar->addAction(stopAction);
    toolbar->addAction(fullScreenAction);
    toolbar->addAction(settingAction);
}

void IcePlayerWindow::createWidgets()
{
    mainGraphics = new QGraphicsView(this);
    QGraphicsScene *scene = new QGraphicsScene(this);
    scene->setBackgroundBrush(Qt::black);
    scene->addPixmap(QPixmap(":/images/logo.bmp"));
    mainGraphics->setScene(scene);

    seekSlider = new QSlider(Qt::Horizontal,this);
    seekSlider->setToolTip(tr("Playback Position"));

    timeLcd = new QLCDNumber(this);
    timeLcd->setSegmentStyle(QLCDNumber::Flat);
    timeLcd->setToolTip(tr("Playback Time"));
    timeLcd->display(" 0:00");

    volumeDial = new QDial(this);
    volumeDial->setRange(0,100);
    volumeDial->setMaximumSize(QSize(32,32));
    volumeDial->setValue(50);

    mplayerController = new MPlayerController(this);
}

void IcePlayerWindow::createLayout()
{
    QHBoxLayout *controlPanel = new QHBoxLayout();
    controlPanel->addWidget(toolbar);
    controlPanel->addWidget(seekSlider);
    controlPanel->addWidget(timeLcd);
    controlPanel->addWidget(volumeDial);

    QVBoxLayout *layout = new QVBoxLayout();
    layout->addWidget(mainGraphics);
    layout->addLayout(controlPanel);

    QWidget *widget = new QWidget(this);
    widget->setLayout(layout);
    setCentralWidget(widget);
}

void IcePlayerWindow::createConnections()
{
    connect(playOrPauseAction, SIGNAL(triggered()), this, SLOT(playOrPause()));
    connect(chooseVideoAction, SIGNAL(triggered()), this, SLOT(chooseVideo()));
    connect(stopAction,SIGNAL(triggered()),this,SLOT(stop()));
    connect(settingAction,SIGNAL(triggered()), this,SLOT(setting()));

    connect(mplayerController,SIGNAL(stateChanged(enum MPlayerController::State)),
                this, SLOT(stateChanged(enum MPlayerController::State)));
    connect(mplayerController,SIGNAL(totalTimeReceived(int)),
                this, SLOT(displayTotalTime(int)));
    connect(mplayerController,SIGNAL(currentTimePositionReceived(int)),
                this, SLOT(displayCurrentTime(int)));
    connect(stopwatchTimer, SIGNAL(timeout()),
            mplayerController, SLOT(requestCurrentTimePosition()));
    connect(seekSlider,SIGNAL(sliderMoved(int)),mplayerController,SLOT(seek(int)));
    connect(volumeDial,SIGNAL(sliderMoved(int)),mplayerController,SLOT(setVolume(int)));
}

void IcePlayerWindow::displayCurrentTime(int sec)
{
    int minutes = sec / 60;
    int seconds = sec % 60;
    timeLcd->display(QString("%1:%2").arg(minutes, 2, 10, QChar(' '))
            .arg(seconds, 2, 10, QChar('0')));
    seekSlider->setValue(sec);
}

void IcePlayerWindow::playOrPause()
{
    if (mplayerController != NULL )
    {
        switch(mplayerController->getCurrentState())
        {
        case MPlayerController::PlayingState:
        case MPlayerController::PausedState:
            mplayerController->playOrPauseMPlayer();
            break;
        case MPlayerController::ErrorState:
        case MPlayerController::DefaultState:
            chooseVideo();
            break;
        case MPlayerController::StoppedState:
            chooseVideo(&currentMediaFile);
            break;
        }
    }
}

void IcePlayerWindow::stop()
{
    mplayerController->stopMPlayer();
}

void IcePlayerWindow::setting()
{
//    SettingDialog *settingDlg = new SettingDialog(this);
//    settingDlg->show();
    SettingDialog *settingDlg = new SettingDialog(this);
    settingDlg->exec();
}

void IcePlayerWindow::chooseVideo(QString *pStrFileName)
{
    mplayerController->stopMPlayer();
    if(pStrFileName == NULL)
    {
        QFileDialog *fileDialog = new QFileDialog(this);
        fileDialog->setWindowTitle("Open Media File");
        fileDialog->setFilter("Media Files(*.mp4 *.avi)");
#ifndef Q_WS_WIN
        fileDialog->showMaximized();
#endif
        if(fileDialog->exec() == QDialog::Accepted)
        {
            currentMediaFile = fileDialog->selectedFiles()[0];
        }
    }
    else
    {
        currentMediaFile = *pStrFileName;
    }
    QRect screenRect;
    screenRect.setTopLeft(mainGraphics->mapToGlobal(QPoint(0,0)));
    screenRect.setBottomRight(mainGraphics->mapToGlobal(QPoint(mainGraphics->width(),
                                                        mainGraphics->height())));
    mplayerController->startMPlayer(currentMediaFile,screenRect,0,volumeDial->value());
}

void IcePlayerWindow::stateChanged(enum MPlayerController::State state)
{
    switch(state)
    {
    case MPlayerController::PlayingState:
        playOrPauseAction->setIcon(QIcon(":/images/pause.png"));
        seekSlider->setEnabled(true);
        stopwatchTimer->start(1000);
        break;
    case MPlayerController::ErrorState:
        playOrPauseAction->setIcon(QIcon(":/images/play.png"));
        break;
    case MPlayerController::PausedState:
        playOrPauseAction->setIcon(QIcon(":/images/play.png"));
        stopwatchTimer->stop();
        break;
    case MPlayerController::StoppedState:
        playOrPauseAction->setIcon(QIcon(":/images/play.png"));
        stopwatchTimer->stop();
        seekSlider->setEnabled(false);
        seekSlider->setValue(seekSlider->minimum());
        break;
    case MPlayerController::DefaultState:
        break;
    }
}
void IcePlayerWindow::displayTotalTime(int sec)
{
    seekSlider->setMaximum(sec);
}

IcePlayerWindow::~IcePlayerWindow()
{
    if (mplayerController != NULL)
    {
        delete mplayerController;
    }
}
